"use strict";
class LFUCache {
    /**
     * 
     * @param {number} capacity 
     */
    constructor(capacity) {
        this.stack = []
        this.map = new Map()
        this.capacity = capacity
    }
    /** 
     * @param {number} key 
     * @param {number} value
     * @return {void}
     */
    put (key, value) {
        let item = this.map.get(key)
        let i = this.stack.indexOf(key)

        if (i > -1) {
            item.value = value
            item.count++
            this.stack.splice(i, 1)
        } else {
            item = { value, count: 1 }
            if (this.stack.length == this.capacity) {
                let k = this.stack.shift()
                this.map.delete(k)
                this.stack.unshift(key)
                this.map.set(key, item)
            }
        }
        i++
        for (; i < this.stack.length; i++) {
            let t = this.map.get(this.stack[i])
            if (item.count < t.count) {
                break;
            }
        }
        this.stack.splice(i, 0, key)
        this.map.set(key, item)
    };
    /** 
     * @param {number} key
     * @return {number}
     */
    get (key) {
        let item = this.map.get(key)
        let i = this.stack.indexOf(key)
        if (i === -1) {
            return -1
        }
        this.stack.splice(i++, 1)
        item.count++

        for (; i < this.stack.length; i++) {
            let t = this.map.get(this.stack[i])
            if (t.count > item.count) {
                break;
            }
        }
        this.stack.splice(i, 0, key)
        return item.value
    };
}


function run (method, args) {
    const cache = new LFUCache(args[0][0]);
    console.log(
        method.slice(1).map((m, i) => {
            let v = cache[m](...args[i + 1])

            console.log(m, args[i + 1], cache.stack.map(t => [t, cache.map.get(t)]))

            return (v || 'null')
        }).join(',')
    )
}

run(
    ["LFUCache", "put", "put", "get", "put", "get", "get", "put", "get", "get", "get"],
    [[2], [1, 1], [2, 2], [1], [3, 3], [2], [3], [4, 4], [1], [3], [4]]
)